package com.goktech.commons.excel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 24252
 * excel二维数组模型
 */
public class ExcelArrayModel implements ExcelModel{
	
	private final static Logger log = LoggerFactory.getLogger(ExcelArrayModel.class);
	
	private static final int FALSE = 1;
	
	private static final int TRUE = 0;
	
	private int[][] modelArray;
	
	public ExcelArrayModel(int x,int y) {
		this.modelArray = new int[x][y];
		for(int i = 0 ;i < x; i++){
			for(int j = 0;j < y; j++){
				modelArray[i][j] = TRUE;
			}
		}
	}
	@Override
	public void add(int x, int y) throws ExcelException {
		x -= 1;y -= 1;
		if(x >= getRowMax() || y >= getCellMax(x+1)){
			if(log.isDebugEnabled())log.debug("当前要添加的坐标x：{}，y：{}，大于原数组的长度length[{}],将会执行复制功能",x,y,this.modelArray.length);
			int maxcell = getAllCellMax();
			modelArray = copy(x+1, y+1 > maxcell ? y+1 : maxcell , modelArray);
			if(log.isDebugEnabled())log.debug("数组复制完成，当前长度length[{}]",this.modelArray.length);
		}
		modelArray[x][y] = FALSE;
	}

	@Override
	public void add(int firstRow, int lastRow, int firstCol, int lastCol) throws ExcelException {
		//纵向复制
		int maxLength = this.getRowMax();
		if(maxLength < lastRow){
			this.modelArray = copy(lastRow, this.getAllCellMax(), modelArray);
		}
		for(int x = firstRow;x < lastRow ; x++){
			if(lastCol > this.getCellMax(x)){
				this.modelArray = copy(x, lastCol, modelArray);
			}
		}
		for(;firstRow <= lastRow ; firstRow++){
			for(int y = firstCol;y <= lastCol ; y++){
				add(firstRow,y);
			}
		}
		
	}

	//获取行的最大值
	@Override
	public int getRowMax() {
		return modelArray.length;
	}

	@Override
	public int getCellMax(int x) throws ExcelException {
		x -= 1;
		if(x > 0 || x < getRowMax()){
			return modelArray[x].length;
		}
		throw new ExcelException("数组越界->x:"+x+" modearray.length:"+modelArray.length);
	}
	
	private int[][] copy(int x,int y,int[][] modelArray){
		int[][] newArray = new int[x][y];
		if(x > modelArray.length){
			System.arraycopy(modelArray, 0, newArray,0, modelArray.length);
			return newArray;
		}else if(y > modelArray[x-1].length){
			int[] array = new int[y];
			System.arraycopy(modelArray[x-1], 0, array,0, modelArray[x-1].length);
			modelArray[x-1] = array;
		}
		return modelArray;
	}
	
	public void print(){
		if(log.isDebugEnabled()){
			StringBuilder sb = new StringBuilder();;
			for(int i=0;i<modelArray.length;i++){
				sb.append(i+"列：");
				for(int j=0;j<modelArray[i].length;j++){
					sb.append(modelArray[i][j]+" ");
				}
				sb.append("\n");
			}
			log.debug("\n{}",sb.toString());
		}
		
	}
	
	@Override
	public boolean get(int x, int y) throws ExcelException{
		if(x > getRowMax()){
			return false;
		}
		if(y > getCellMax(x)){
			return false;
		}
		x -= 1;
		y -= 1;
		return this.modelArray[x][y] == TRUE;
	}
	
	/**
	 * 返回二维数组模型中单行最大长度
	 * @return
	 */
	private int getAllCellMax(){
		int sum = 0 ;
		for(int[] array : this.modelArray){
			if(array.length > sum){
				sum = array.length;
			}
		}
		return sum;
	}
	@Override
	public int[] getLeftPoint() {
		int x = 0;
		int[] result = {x,0};
		for(int i = 0;i<this.modelArray[0].length;i++){
			if(this.modelArray[x][i] == 0){
				result[1] = i;
				return result;
			}
		}
		result[1] = this.modelArray[x].length;
		return result;
	}
	
	/**
	 *确定中间坐标点的算法 
	 * @throws ExcelException 
	 */
	@Override
	public int[] getCenterPoint() throws ExcelException {
		int x = 0,y = 0;
		for(;y < this.modelArray.length && x < this.modelArray[y].length;) {
			int tempInt = 0;
			for(int i = x;i < this.modelArray[y].length;i++) {
				if(get(x+1, y+1)) {
					tempInt++;
					break;
				}
			}
			if(tempInt > 0) {
				x ++;y++;
			}else {
				for(int i = y;i < this.modelArray.length;i++) {
					if(get(x+1, y+1)) {
						tempInt++;
						break;
					}
				}
				if(tempInt > 0) {
					x ++;y++;
				}
			}
			System.out.println(tempInt);
			if(tempInt == 0) {
				break;
			}
		}
		return new int[] {x+1,y+1};
	}
	@Override
	public int[] getBottomPoint() {
		int y = 0;
		int[] result = {0,0};
		for(int i=0;i<this.modelArray.length;i++){
			if(this.modelArray[i][y] == 0){
				result[0] = i;
				return result;
			}
		}
		result[0] = this.modelArray.length;
		return result;
	}
}
